package com.yueyang.sojourn.server.controller.merchant;

import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingReceiverResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.pagehelper.PageInfo;
import com.yueyang.sojourn.server.common.baymax.web.result.JAssert;
import com.yueyang.sojourn.server.config.WxPayProperties;
import com.yueyang.sojourn.server.controller.BaseController;
import com.yueyang.sojourn.server.controller.model.JsonResult;
import com.yueyang.sojourn.server.model.dto.AddMerchantDto;
import com.yueyang.sojourn.server.model.po.SojournMerchant;
import com.yueyang.sojourn.server.model.po.SojournProject;
import com.yueyang.sojourn.server.model.vo.SojournMerchantSimpleVo;
import com.yueyang.sojourn.server.model.vo.SojournMerchantVo;
import com.yueyang.sojourn.server.service.sojourn.merchant.SojournMerchantService;
import com.yueyang.sojourn.server.service.sojourn.pay.PayServiceWill;
import com.yueyang.sojourn.server.service.sojourn.project.SojournProjectService;
import com.yueyang.uc.model.UcUserV1;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 商户后台服务
 * @author andy.yang
 * @version v1
 * @summary
 * @Copyright (c) 2019, yueyang Group All Rights Reserved.
 * @since 2020/3/17
 */
@Slf4j
@Api(tags = "商户 API")
@RestController
@RequestMapping("/sojourn/merchant")
public class SojournMerchantController extends BaseController {
    @Autowired
    SojournMerchantService merchantService;
    @Autowired
    SojournProjectService projectService;
    @Autowired
    PayServiceWill payServiceWill;
    @Autowired
    WxPayProperties wxPayProperties;

    /**
     * 创建商户数据验证
     * @param merchantDto
     * @return
     */
    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "创建商户数据验证")
    @PostMapping("/valid")
    public JsonResult<Long> validOrder(@RequestBody @Validated AddMerchantDto merchantDto, BindingResult bindingResult) {
        return validAdd(merchantDto,bindingResult);
    }


        /**
         * 创建
         * @param merchantDto
         * @return
         */
    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "创建商户")
    @PostMapping("")
    public JsonResult<Long> createOrder(@RequestBody @Validated AddMerchantDto merchantDto, BindingResult bindingResult) {
        JsonResult rs = validAdd(merchantDto,bindingResult);
        if(!rs.getSuccess()){
            return rs;
        }
        Long loginUserId = getLoginUserId();
        SojournMerchant merchant = new SojournMerchant();
        BeanUtils.copyProperties(merchantDto,merchant);
        merchant.setCreator(loginUserId);
        merchantService.add(merchant);
        rs.setData(merchant.getId());
        return rs;
    }

    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "商户列表分页查询")
    @GetMapping("/page")
    public PageInfo<SojournMerchantVo> findPage(@ApiParam(value = "关键词:商户或微信支付商户号") @RequestParam(required = false) String keyWord,
                                                @RequestParam int pageNo,
                                                @RequestParam int pageSize) {
        PageInfo<SojournMerchant> pageInfo = merchantService.findPage(keyWord,null,pageNo,pageSize);
        PageInfo<SojournMerchantVo> pageInfoRs = new PageInfo<>();
        BeanUtils.copyProperties(pageInfo,pageInfoRs);
        pageInfoRs.setList(new ArrayList<>());
        List<Long> creators = new ArrayList<>();
        List<Long> projectIds = new ArrayList<>();
        pageInfo.getList().stream().forEach((po)->{
            if(!creators.contains(po.getCreator())) {
                creators.add(po.getCreator());
            }
            if(!projectIds.contains(po.getProjectId())){
                projectIds.add(po.getProjectId());
            }
        });

        //查询项目
        Map<Long,SojournProject> projectMap = new HashMap<>();
        if(!projectIds.isEmpty()){
            List<SojournProject> projects = projectService.findByIds(projectIds);
            projects.stream().forEach((p) -> {projectMap.put(p.getId(),p);});
        }

        //查询用户
        final Map<Long,UcUserV1> userMap = new HashMap<>();
        if(!creators.isEmpty()){
            userMap.putAll(findMapByIds(creators));
        }

        pageInfo.getList().stream().forEach((po)->{
            SojournMerchantVo vo = new SojournMerchantVo();
            BeanUtils.copyProperties(po,vo);
            vo.setCreatorPhoneShow(userMap.get(po.getCreator()) == null ? null : userMap.get(po.getCreator()).getPhoneShow());
            vo.setProjectName(projectMap.get(po.getProjectId()) == null ? null : projectMap.get(po.getProjectId()).getName());
            pageInfoRs.getList().add(vo);
        });

        return pageInfoRs;
    }

    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "商户简单提示列表-分页查询")
    @GetMapping("/simple/page")
    public PageInfo<SojournMerchantSimpleVo> findSimplePage(@ApiParam(value = "关键词:商户或微信支付商户号") @RequestParam(required = false) String keyWord,
                                                @RequestParam int pageNo,
                                                @RequestParam int pageSize) {
        PageInfo<SojournMerchant> pageInfo = merchantService.findPage(keyWord,null,pageNo,pageSize);
        PageInfo<SojournMerchantSimpleVo> pageInfoRs = new PageInfo<>();
        BeanUtils.copyProperties(pageInfo,pageInfoRs);
        pageInfoRs.setList(new ArrayList<>());

        pageInfo.getList().stream().forEach((po)->{
            SojournMerchantSimpleVo vo = new SojournMerchantSimpleVo();
            BeanUtils.copyProperties(po,vo);
            pageInfoRs.getList().add(vo);
        });

        return pageInfoRs;
    }


    @ApiImplicitParam(name = "X-Token", paramType = "header", required = true)
    @ApiOperation(value = "根据项目查询商户详情")
    @GetMapping("/project/{projectId}")
    public SojournMerchantVo findByProjectId(@ApiParam(value = "项目id") @PathVariable(value = "projectId") Long projectId) {
        SojournMerchant merchant = merchantService.findByProjectId(projectId);
        if(merchant == null){
            return null;
        }

        SojournMerchantVo vo = new SojournMerchantVo();
        BeanUtils.copyProperties(merchant,vo);
        //查询项目
        SojournProject project = projectService.selectByPrimaryKey(merchant.getProjectId());
        UcUserV1 ucUserV1 = findUserById(merchant.getCreator());
        vo.setProjectName(project.getName());
        vo.setCreatorPhoneShow(ucUserV1.getPhoneShow());
        return vo;
    }


    private JsonResult validAdd(AddMerchantDto merchantDto, BindingResult bindingResult){
        FieldError fieldError = bindingResult.getFieldError();
        if (Objects.nonNull(fieldError)) {
            JAssert.justFailed(fieldError.getDefaultMessage());
        }
        if(wxPayProperties.getMchId().equals(merchantDto.getWxMerchantNo())){
            return fail("不允许配置服务商商户");
        }
        SojournMerchant merchantOldByName = merchantService.findByName(merchantDto.getName().trim());
        if(merchantOldByName != null){
            return fail(10,"此商户名称已存在");
        }
        SojournMerchant merchantOldByWxNo = merchantService.findByWxMerchantNo(merchantDto.getWxMerchantNo());
        if(merchantOldByWxNo != null){
            return fail(20,"此微信支付商户号已存在");
        }

        SojournMerchant merchantOldByProjectId = merchantService.findByProjectId(merchantDto.getProjectId());
        if(merchantOldByProjectId != null){
            return fail(30,"此项目已绑定其它商户");
        }
        SojournProject project = projectService.selectByPrimaryKey(merchantDto.getProjectId());
        if(project == null){
            return fail(31,"项目不存在");
        }

        //验证：商户必须正确
        try {
            payServiceWill.addWxPlatformShareReceiver(merchantDto.getWxMerchantNo());
        } catch (WxPayException e) {
            log.error(e.getMessage(),e);
            if("MCH_NOT_EXISTS".equals(e.getErrCode()) || "USER_NOT_EXIST".equals(e.getErrCode())){
                return fail("商户号不正确");
            }else if("ACCOUNTERROR".equals(e.getErrCode())){
                return fail("商户未开通支付功能");
            }else if("NOAUTH".equals(e.getErrCode())){
                return fail("商户未授权分账");
            }
            return fail("系统忙，稍后重试");
        }
        return ok();
    }
}
